﻿using Volo.Abp.DependencyInjection;

namespace PLCS.Domain.PLCConfigs;

public class PLCCacheService : ISingletonDependency
{
    private static List<PLCConfig> _plcConfigs;
    private readonly IPLCConfigRepository _pLCConfigRepository;
    private readonly object _lock = new object();

    public PLCCacheService(IPLCConfigRepository pLCConfigRepository)
    {
        _plcConfigs = new List<PLCConfig>();
        _pLCConfigRepository = pLCConfigRepository;
    }

    public async Task InitalAsync()
    {
        _plcConfigs = await LoadConfigurationFromDatabase();
    }

    private async Task<List<PLCConfig>> LoadConfigurationFromDatabase()
    {
        var configs = await _pLCConfigRepository.GetListInUseWithDetailsAsync();
        return configs.ToList();
    }

    public async Task<List<PLCConfig>> GetConfigurations()
    {
        if (!_plcConfigs.Any())
            await InitalAsync();
        return _plcConfigs;
    }

    public void UpdateConfiguration(PLCConfig config)
    {
        lock (_lock)
        {
            var configDto = _plcConfigs.SingleOrDefault(c => c.PLCNo == config.PLCNo);
            if (configDto == null)
                _plcConfigs.Add(config);
            else
            {
                _plcConfigs.Remove(configDto);
                _plcConfigs.Add(config);
            }
        }
    }

    public void DeleteConfiguration(PLCConfig config)
    {
        lock (_lock)
        {
            var configDto = _plcConfigs.SingleOrDefault(c => c.PLCNo == config.PLCNo);
            if (configDto != null)
                _plcConfigs.Remove(configDto);
        }
    }

    public void UpdateConfigurations(List<PLCConfig> configs)
    {
        lock (_lock)
        {
            foreach (var config in configs)
            {
                var existingConfig = _plcConfigs.FirstOrDefault(c => c.PLCNo == config.PLCNo);
                if (existingConfig != null)
                {
                    _plcConfigs.Remove(existingConfig);
                }

                _plcConfigs.Add(config);
            }
        }
    }

    public void UpdatePLCReadDatas(List<PLCReadData> pLCReadDatas)
    {
        lock (_lock)
        {
            var groupedData = pLCReadDatas.GroupBy(d => d.PLCConfigId); // 根据 PLCConfigId 属性进行分组

            foreach (var group in groupedData)
            {
                var configId = group.Key;
                var groupItems = group.ToList();

                var existingConfig = _plcConfigs.FirstOrDefault(c => c.Id == configId);
                if (existingConfig != null)
                {
                    foreach (var item in groupItems)
                    {
                        if (existingConfig.PLCReadDatas == null)
                            continue;
                        var existingReadData = existingConfig.PLCReadDatas.FirstOrDefault(x => x.PLCReadDataNo == item.PLCReadDataNo);
                        if (existingReadData != null)
                        {
                            existingConfig.PLCReadDatas.Remove(existingReadData);
                        }

                        existingConfig.PLCReadDatas.Add(item);
                    }
                }
            }
        }
    }
}